﻿#include "ThreadPool.h"
#include "../Base/Log.h"
ThreadPool* ThreadPool::createNew(int num)
{
    return new ThreadPool(num);
}

ThreadPool::ThreadPool(int num) :
    mThreads(num),
    mQuit(false)
{
    createThreads();
}

ThreadPool::~ThreadPool()
{
    cancelThreads();
}

void ThreadPool::addTask(ThreadPool::Task& task)
{   
    std::unique_lock <std::mutex> lck(mMtx); //向任务队列中增减任务，通常需要加锁，以保证线程安全，确保了在同一时刻只有一个线程可以修改任务队列。
    mTaskQueue.push(task);
    mCon.notify_one();//如果任务队列为空，线程可能会进入等待状态（例如通过条件变量等待任务到来）。
}

void ThreadPool::loop(){

    while(!mQuit){

        std::unique_lock <std::mutex> lck(mMtx);
        if (mTaskQueue.empty()) {
            mCon.wait(lck); //任务队列为空时，释放锁并进入等待状态。
        }
     

        if(mTaskQueue.empty()) //避免虚假唤醒
            continue;

        Task task = mTaskQueue.front();
        mTaskQueue.pop(); //有任务，则取出任务

        task.handle(); //执行任务
    }

}

void ThreadPool::createThreads()
{
    std::unique_lock <std::mutex> lck(mMtx);
    for(auto & mThread : mThreads)
        mThread.start(this);
}

void ThreadPool::cancelThreads()
{
    std::unique_lock <std::mutex> lck(mMtx);
    mQuit = true; //设置退出标志
    mCon.notify_all(); //唤醒所有线程
    for(auto & mThread : mThreads)
        mThread.join(); //等待线程完成

    mThreads.clear(); //清空线程列表
}

void ThreadPool::MThread::run(void* arg)
{
    ThreadPool* threadPool = (ThreadPool*)arg;
    threadPool->loop();
}